package aquarium.items;

import java.awt.Graphics;
import java.awt.Image;
import java.awt.Point;
import java.awt.Rectangle;
import java.util.Collection;

import aquarium.factory.FishType;
import aquarium.gui.Aquarium;
import aquarium.time.TManager;
import aquarium.time.TimerKind;

public abstract class AquariumItem {
	private Image _image;
	private Point _position;
	private int _size;
	private int _adult_size;
	private boolean _destructible; // peut etre detruit
	private boolean _letal; // tue lorsqu'il est rencontré
	private boolean _destroy_me = false;

	private static final int MIN_WIDTH = 30, MAX_WIDTH = 60;

	public AquariumItem(Image image, 
			Point position, 
			int size, 
			boolean destructible,
			boolean letal,
			long move_delay,
			TManager tmanager) {
		this._size = MIN_WIDTH;
		this._image = image;
		this._position = new Point(position);
		this._adult_size = size;
		this._destructible = destructible;
		this._letal = letal;
		if (tmanager != null && move_delay > 0)
			tmanager.addObserver(this, TimerKind.Position, move_delay);
	}


	public void update(TimerKind kind, Collection<AquariumItem> items, Aquarium aquarium) {
		System.out.println("Update ! Je suis un AquariumItem et j'ai recu un appel sur une " + kind + "\n CE N'EST PAS NORMAL !!!\nQuoi que ca dépends de l'alignement de saturne et de ...");
	}

	public void set_image(Image image) {
		this._image = image;
	}
	
	public Point get_position() {
		return _position;
	}

	public void set_position(Point _position) {
		this._position = _position;
	}

	public int get_size() {
		return _size;
	}

	public int get_adult_size(){
		return _adult_size;
	}

	public void set_size(int _size) {
		this._size = _size;
	}

	public Image get_image() {
		return _image;
	}

	public boolean is_destructible() {
		return _destructible;
	}

	public boolean is_letal() {
		return _letal;
	}

	public boolean must_be_destroyed(){
		return _destroy_me;
	}

	public void destroy(){
		_destroy_me = true;
	}

	static public int getMaxWidth() {
		return MAX_WIDTH;
	}

	static public int getMinWidth() {
		return MIN_WIDTH;
	}

	// retourne le rectangle englobant
	public Rectangle rectangle() {
		return new Rectangle(_position.x, _position.y, _size-1, _size-1);
	}

	public void draw(Graphics g) {
		int largeur = _size; // default tete a gauche
		int posx = _position.x;
		if(this instanceof MobileItem)
			if((((MobileItem)this).get_target().x)-(this.get_position().x+_size/2)>0){ // tete a droite
				/*La position Point est un coin du rectangle donc position.x + width/2 prend le centre horizontal*/
				largeur = -_size;
				posx = _position.x+_size;
			}
		g.drawImage(_image, posx, _position.y, largeur, _size, null); 
	}

	/*
	 * parcourt la collection et retourne vrai d�s  
	 * que le rectangle de cet item en coupe un autre 
	 * faux � la fin du parcours (aucune intersection)
	 */

	public boolean intersects(Collection<AquariumItem> c) {
		for(AquariumItem ai : c) {
			if(ai.rectangle().intersects(rectangle())){
				return true;
			}
		}
		return false;
	}

	public boolean killby(Collection<AquariumItem> items){
		synchronized(items){
			for(AquariumItem ai : items) {
				// Verification des poissons qui rencontre un caillou et qui meurt
				if (ai.rectangle().intersects(this.rectangle())){ // verification de collision
					if(this._destructible && ai._letal){
						if((ai instanceof Bubble) && ((Bubble)ai).isFishCreator((Fish)this))
							return false;
						return true;
					}
					if(ai._destructible && this instanceof Fish)
						// Verification des poissons qui se font manger par des PiscivoreFish
						if((((Fish)ai).is_piscivore()) && (!(((Fish)this).is_piscivore())) && 
								(ai._size > this._size)) {
							ai.changeSize('a'); // Le PiscivoreFish grossit
							return true;
						}
				}
			}
		}
		return false;
	}

	public void dead(Collection<AquariumItem> items){
		synchronized (items){
			for(AquariumItem item : items){
				if (item.killby(items))
					item.destroy();
				if(item.extern_aqua())
					item.destroy();
			}
		}
	}

	public boolean extern_aqua(){
		if((this._position.x <= 0) || (this._position.x >= Aquarium.SIZE_AQUA_X))
			return true;
		if((this._position.y <= 0) || (this._position.y >= Aquarium.SIZE_AQUA_Y))
			return true;
		return false;
	}

	public FishType egg_possibility(Collection<AquariumItem> items){
		synchronized(items){
			for(AquariumItem ai : items) {
				if (ai instanceof MobileItem && !(ai instanceof Bubble)){
					if (ai.rectangle().intersects(this.rectangle())){
						if(!((Fish)ai).get_sex().equals(((Fish)this).get_sex())){
							if((ai instanceof PiscivoreFish) && (this instanceof PiscivoreFish))
								return FishType.Piscivore;
							if((ai instanceof OneSecondFish) && (this instanceof OneSecondFish))
								return FishType.OneSecond;
							if((ai instanceof NormalFish) && (this instanceof NormalFish))
								return FishType.Normal;
						}
					}
				}
			}
		}
		return null;
	}

	public void changeSize(char type){ // Permet de faire grossir le poisson (toutes conditions)
		int DEFAULT_SIZE = 1;
		if(type == 'a')
			if (((AquariumItem) this)._adult_size < Fish.getMaxWidth()-(DEFAULT_SIZE-1))
				((AquariumItem) this)._adult_size = (((AquariumItem) this)._adult_size + DEFAULT_SIZE);
		if(type == 's')
			if (((AquariumItem) this)._size < this._adult_size-(DEFAULT_SIZE-1))
				((AquariumItem) this)._size = (((AquariumItem) this)._size + DEFAULT_SIZE);

	}


}
